import axios from "axios";

// 导入配置
import config from "../config";

//导入路由,用于router跳转
import router from "../router";
import storage from "../utils/storage";

const TOKEN_INVALID = "Token 认证失败,请重新登录";
const NETWORK_ERROR = "网络请求失败,请稍后再试";
// 创建axios实例,添加全局配置
const service = axios.create({
  // 从配置项中取出baseURL
  baseURL: config.baseApi,
  //   超时时间,8s
  timeout: 8000,
});

// 请求拦截
service.interceptors.request.use((req) => {
  //获取请求头
  const headers = req.headers;

  //如果请求头中,没有验证信息,给个默认值
  if (!headers.Authorization) {
    const { token } = storage.getItem("userInfo") || "hello";
    // 在请求头中,携带token
    headers.Authorization = "Bearer " + token;
  }
  //   返回请求信息,接着往后走

  return req;
});

// 响应拦截
service.interceptors.response.use((res) => {
  // 从响应的数据中, 获取code,data, msg
  const { code, data, msg } = res.data;
  // 如果状态码0, 直接返回data
  if (code === 0) {
    return data;
  } else if (code === 5001) {
    // 如果错误码5001, 报错, 返回错误信息
    console.error(TOKEN_INVALID); // 页面弹框
    storage.clearItem("userInfo");
    // 路由跳转登录页面, 给一些时间, 比如1.5s
    // setTimeout(() => {
    //   router.push("/login");
    // }, 1500);
    return Promise.reject(TOKEN_INVALID); // 控制台
  } else {
    // 走到这一步, 就是其他报错
    console.error(msg || NETWORK_ERROR);
    if (msg === "账号或密码不正确") {
      alert(msg);
    }
    return Promise.reject(msg || NETWORK_ERROR);
  }
});

// 封装request
function request(options) {
  // 默认get请求
  options.method = options.method || get;
  //   有时候方法是大写的,所以先转为小写
  if (options.method.toLowerCase() === "get") {
    options.params = options.data;
  }
  // 局部设置mock
  if (typeof options.mock !== "undefined") {
    config.mock = options.mock;
  }
  //   如果是生产环境,一定要调用线上的正式api
  if (config.env === "prod") {
    service.defaults.baseURL = config.baseApi;
  } else {
    // 判断是否开启了mock,如果开了,走mock,没开的话,走线上正式api
    service.defaults.baseURL = config.mock ? config.mockApi : config.baseApi;
  }
  return service(options);
}

["get", "post", "put", "delete", "patch"].forEach((element) => {
  request[element] = (url, data, options) => {
    return request({
      url,
      data,
      method: element,
      ...options,
    });
  };
});

export default request;
